# -*- coding: utf-8 -*-

from openerp.osv import osv
from openerp.osv import fields
from openerp.osv import orm
from openerp import SUPERUSER_ID
from openerp.addons.web.http import request
import random
import math
# import re


class sale_order(osv.osv):
    _inherit = 'sale.order'

    # def action_cancel(self, cr, uid, ids, context=None):
    #     model_data_obj = self.pool.get('ir.model.data')
    #     order_type_id = model_data_obj.xmlid_to_res_id(
    #         cr, SUPERUSER_ID, 'dftg_ext.dftg_order_type_data_point_order')
    #     for sale_order in self.browse(cr, uid, ids, context=context):
    #         user = sale_order.partner_id.user_ids and sale_order.partner_id.user_ids[0]
    #         if sale_order.order_type_id.id == order_type_id and user:
    #             sale_change_point_balance = sale_order.amount_total * sale_order.redeem_ratio
    #             user.write({'point_balance': sale_change_point_balance + user.point_balance})
    #             self.pool.get('partner.changed.point').create(cr, uid, {
    #                 'partner_id': sale_order.partner_id.id,
    #                 'changed_point': sale_change_point_balance,
    #                 'point_balance': sale_change_point_balance + user.point_balance,
    #                 'so_id': sale_order.id,
    #                 'note': "%s积分兑换退单" % (sale_order.name),
    #             }, context=context)
    #     return super(sale_order, self).action_cancel(cr, uid, ids, context=context)

    # 自定义订单名称的格式为：JF_S****
    def create(self, cr, uid, vals, context=None):
        if 'shop_id' in vals:
            shop_ids = self.pool.get('shop').search(cr, uid, [('id', '=', vals['shop_id'])],context=context)
            shop = self.pool.get('shop').browse(cr, uid, shop_ids, context=context)
            #这里需要区分内部积分商城还是企业商城，来进行序列号的生成
            if shop.type == 'integral':
                vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'point_exchange_order') or '/'
        return super(sale_order, self).create(cr, uid, vals, context=context)


    def change_points(self, cr, uid, ids, context=None):
        change_obj = self.pool.get('partner.changed.point')
        for order in self.browse(cr, uid, ids, context=context):
            point_balance = order.partner_id.point_balance

            for line in order.order_line:
                point_balance -= line.price_subtotal * order.redeem_ratio
                change_obj.create(cr, uid, {
                    'partner_id': order.partner_id.id,
                    'changed_point': -line.price_subtotal * order.redeem_ratio,
                    'product_id': line.product_id.id,
                    'point_balance': point_balance,
                    'so_id': order.id,
                }, context=context)

            order.partner_id.write({'point_balance': point_balance})

    def prepare_message(self, message):

        # @正翔 使用正则表达式去除掉所有html语义标签
        # escape_regexp = re.compile(r'</?[\w]*?>|\&lt;/?[\w]*?&gt;')
        try:
            date = message.create_date.split()[0].split('-', 1)[1]
        except IndexError:
            date = message.create_date.split('-', 1)[1]

        return {
            # 'message': escape_regexp.sub('', message.body).replace('•', '<br >•'),
            'message': message.body,
            'date': date,
            # 'user': message.author_id.id == admin_id and u'系统消息' or message.author_id.name,
            'user': message.type == 'notification' and u'系统消息' or message.author_id.name,
            'admin': message.type == 'notification',
        }

    def _get_message_by_website(self, cr, uid, order_id, context=None):
        # @正翔 消息界面上显示的消息的接口
        # ir_model_data = self.pool.get('ir.model.data')
        order = self.browse(cr, uid, order_id, context=context)
        # admin_id = ir_model_data.xmlid_to_res_id(cr, uid, 'base.partner_root')

        res = []
        for message in order.message_ids:
            res.append(self.prepare_message(message))

        return res

    def _anonymous(self, name):
        if name and isinstance(name, (str, unicode)):
            return name[0] + '***' + name[-1]
        else:
            return name

    def get_evaluations(self, cr, uid, template_id, context=None):
        evaluation_obj = self.pool.get('order.evaluation')

        evaluation_ids = evaluation_obj.search(cr, uid, [('line_id.product_id.product_tmpl_id', '=', template_id)], context=context)

        res = []
        for evaluation in evaluation_obj.browse(cr, uid, evaluation_ids, context=context):
            res.append({
                    'user_id': evaluation.user_id.id,
                    'username': evaluation.is_anonymous and self._anonymous(evaluation.user_id.name) or evaluation.user_id.name,
                    'description': evaluation.description,
                    'variants': ','.join(value.attribute_id.name + ':' + value.name for value in evaluation.line_id.product_id.attribute_value_ids),
                })

        return res or False

    def get_shopping_evaluations(self, cr, uid, order_id, context=None):
        res = []
        for evaluation in self.browse(cr, uid, order_id, context=context).evaluation_ids:
            res.append({
                    'id': evaluation.id,
                    'user_id': evaluation.user_id.id,
                    'username': evaluation.is_anonymous and self._anonymous(evaluation.user_id.name) or evaluation.user_id.name,
                    'description': evaluation.description,
                })

        return res or False

    _columns = {
        'shop_id': fields.many2one('shop', u'商城'),
        'redeem_ratio': fields.float(u'积分兑换比'),
        'evaluation_ids': fields.one2many('order.evaluation', 'order_id', u'评价'),
    }


class sale_order_line(osv.osv):
    _inherit = 'sale.order.line'

    def invoice_line_create(self, cr, uid, ids, context=None):
        res = super(sale_order_line, self).invoice_line_create(cr, uid, ids, context=context)
        order_ids = list(set(line.order_id.id for line in self.browse(cr, uid, ids, context=context)))

        if len(order_ids) == 1:
            order = self.pool.get('sale.order').browse(cr, uid, order_ids[0], context=context)
            if order.shop_id and order.shop_id.type == 'integral' and len(order.order_line) == len(ids):
                product_template = self.pool.get('ir.model.data').get_object_reference(
                    cr, uid, 'dftg_ext', 'dftg_product_point_payment_product_template')[1],
                product_id = self.pool.get('product.product').search(cr, uid, [('product_tmpl_id','in',product_template)])
                product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)

                account_id = product.property_account_income.id
                if not account_id:
                    account_id = product.categ_id.property_account_income_categ.id
                    if not account_id:
                        raise osv.except_osv(_('Error!'),
                                _('Please define income account for this product: "%s" (id:%d).') % \
                                    (product_template.name, product.id,))

                res.append(self.pool.get('account.invoice.line').create(cr, uid, {
                    'name': u'积分支付',
                    'origin': order.name,
                    'account_id': account_id,
                    'price_unit': -order.amount_total,
                    'quantity': 1,
                    'product_id': product.id,
                    'account_analytic_id': order.project_id and order.project_id.id or False,
                }, context=context))

        return res

    def get_old_evaluation_for_evaluation(self, cr, uid, id, evaluation_id=None, context=None):
        if evaluation_id and evaluation_id != 'false':
            return False

        line = self.browse(cr, uid, id, context=context)
        res = []
        for evaluation in line.evaluation_ids:
            res.append({'description': evaluation.description, 'id': evaluation.id})

        return res or False

    def get_product_for_evaluation(self, cr, uid, id, evaluation_id=None, context=None):
        product = False
        if evaluation_id and evaluation_id != 'false':
            evaluation = self.pool.get('order.evaluation').browse(cr, uid, evaluation_id, context=context)
            if evaluation.line_id:
                product = evaluation.line_id.product_id
        else:
            product = self.browse(cr, uid, id, context=context).product_id

        if product:
            return {
                'url': '/website/image/product.template/' + str(product.id) + '/image',
                'name': product.name,
                'variants': ','.join(value.attribute_id.name + ':' + value.name for value in product.attribute_value_ids),
            }

    def open_evaluation(self, cr, uid, ids, context=None):
        for line in self.browse(cr, uid, ids, context=context):
            return {
                'name': u'客户评价',
                'type': 'ir.actions.act_window',
                'res_model': 'order.evaluation',
                'domain': [('id', 'in', [evaluation.id for evaluation in line.evaluation_ids])],
                'view_type': 'form',
                'view_mode': 'tree',
            }

    _columns = {
        'evaluation_ids': fields.one2many('order.evaluation', 'line_id', u'评价'),
    }


class shopping_cart(osv.osv):
    _name = 'shopping.cart'
    _rec_name = 'partner_id'

    def _get_cart_quantity(self, cr, uid, ids, field_name, arg, context=None):
        res = {}
        for cart in self.browse(cr, uid, ids, context=context):
            res.update({cart.id: sum(line.product_uom_qty for line in cart.cart_line)})

        return res

    def _amount_line_tax(self, cr, uid, line, context=None):
        val = 0.0
        for c in self.pool.get('account.tax').compute_all(cr, uid, line.taxes_id, line.price_unit, line.product_uom_qty, line.product_id, line.order_id.partner_id)['taxes']:
            val += c.get('amount', 0.0)
        return val

    def _get_amount(self, cr, uid, ids, field_name, arg, context=None):
        res = {}
        # 需要获取含税价格
        for cart in self.browse(cr, uid, ids, context=context):
            amount_untax, amount_tax = 0, 0
            for line in cart.cart_line:
                amount_tax += self._amount_line_tax(cr, uid, line, context=context)
                amount_untax += line.price_subtotal

            res[cart.id] = {
                'amount_total': amount_tax + amount_untax,
                'amount_tax': amount_tax,
            }

        return res

    def _get_state(self, cr, uid, ids, field_name, arg, context=None):
        res = dict.fromkeys(ids, 'draft')
        for cart in self.browse(cr, uid, ids, context=context):
            if all(line.state != 'draft' for line in cart.cart_line):
                res.update({cart.id: 'done'})

        return res

    def _get_shopping_cart(self, cr, uid, ids, context=None):
        return list(set(line.order_id.id for line in self.browse(cr, uid, ids, context=context) if line.order_id))

    _columns = {
        'shop_id': fields.many2one('shop', u'商城'),
        'partner_id': fields.many2one('res.partner', u'客户'),
        'user_id': fields.many2one('res.users', u'用户'),
        'pricelist_id': fields.many2one('product.pricelist', u'价格文件表'),
        'cart_line': fields.one2many('shopping.cart.line', 'order_id',
                    u'购物车明细'),
        'website_order_line': fields.one2many('shopping.cart.line', 'order_id',
                    u'购物车明细'),
        'company_id': fields.many2one('res.company', u'公司'),
        'cart_quantity': fields.function(_get_cart_quantity, type='integer', string=u'购物车数量'),
        'amount_total': fields.function(_get_amount, multi='amount', string=u'总额'),
        'amount_tax': fields.function(_get_amount, multi='amount', string=u'税金额'),
        'temp': fields.boolean(u'临时'),
        'state': fields.function(_get_state, type='selection', selection=[('draft', u'使用中'), ('done', u'完成')], string=u'状态',
            store={
                'shopping.cart.line': (_get_shopping_cart, ['state'], 10)
        }),
    }

    _defaults = {
        'company_id': lambda self, cr, uid, ctx=None: self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=ctx).company_id.id,
    }

    def _prepare_order_vals(self, cr, uid, cart, line_ids=None, value=None, context=None):
        shop = self.pool.get('shop').browse(cr, SUPERUSER_ID, request.session['shop_id'], context=context)
        res = value or {}
        res.update({
            'partner_id': cart.partner_id.id,
            'pricelist_id': cart.pricelist_id.id,
            'company_id': cart.company_id.id,
            'order_line': [],
            'redeem_ratio': shop.redeem_ratio,
            'shop_id': request.session.get('shop_id'),
        })

        for line in cart.cart_line:
            if line.state != 'draft' or (line_ids and line.id not in line_ids):
                continue

            res['order_line'].append([0, False, self._prepare_order_line_vals(cr, uid, line, context=context)])
            line.write({'state': 'done'})

        return res

    def _prepare_order_line_vals(self, cr, uid, line, context=None):
        context = context or {}

        return {
            'product_id': line.product_id.id,
            'product_uom_qty': line.product_uom_qty,
            'price_unit': line.price_unit,
            'name': line.name,
        }

    def create_sale_order_by_product(self, cr, uid, product_id, product_qty, value=None, context=None):
        user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
        product = self.pool.get('product.product').browse(cr, SUPERUSER_ID, product_id, context=context)
        shop = self.pool.get('shop').browse(cr, SUPERUSER_ID, request.session['shop_id'], context=context)

        context = context or {}
        res = value or {}
        res.update({
            'partner_id': user.partner_id.id,
            'shop_id': request.session.get('shop_id'),
            'redeem_ratio': shop.redeem_ratio,
            'order_line': [[0, False, {
                'product_id': product_id,
                'product_uom_qty': product_qty,
                'price_unit': context.get('ceil', False) and math.ceil(product.list_price) or product.list_price,
                'name': product.name,
            }]],
        })

        return self.pool.get('sale.order').create(cr, SUPERUSER_ID, res, context=context)

    def create_partial_sale_order(self, cr, uid, cart, line_ids, value=None, context=None):
        order_obj = self.pool.get('sale.order')

        if not cart or cart.state == 'done':
            return False

        return order_obj.create(
            cr, uid, self._prepare_order_vals(
                cr, uid, cart, line_ids=line_ids, value=value, context=context), context=context)

    # 通过购物车创建一个销售订单
    def create_sale_order(self, cr, uid, cart_id, context=None):
        order_obj = self.pool.get('sale.order')

        cart = self.browse(cr, uid, cart_id, context=context)
        if not cart or cart.state == 'done':
            return False

        sale_order_id = order_obj.create(cr, uid, self._prepare_order_vals(cr, uid, cart, context=context), context=context)

        return sale_order_id

    def _merge_cart_from_temp(self, cr, uid, from_cart_id, to_cart_id, context=None):
        line_obj = self.pool.get('shopping.cart.line')

        # {产品ID：（产品数量，产品所在购物车行ID，是否需要更新）}
        product_vals = {}
        for line in self.browse(cr, uid, from_cart_id, context=context).cart_line:
            product_vals.update({line.product_id.id: (line.product_uom_qty, line.id, False)})

        for line in self.browse(cr, uid, to_cart_id, context=context).cart_line:
            old_vals = product_vals.get(line.product_id.id, False)
            if old_vals:
                product_vals.update({
                        line.product_id.id: (old_vals[0] + line.product_uom_qty, old_vals[1], True)
                    })
            else:
                product_vals.update({
                        line.product_id.id: (line.product_uom_qty, False, True)
                    })

        for product_id, vals in product_vals.iteritems():
            if not vals[2]:
                continue

            if vals[1]:
                line_obj.write(cr, uid, vals[1], {'product_uom_qty': vals[0]}, context=context)
                continue

            product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
            values = {
                'order_id': from_cart_id,
                'product_id': product_id,
                'product_uom_qty': vals[0],
                'name': product.description_sale and "%s\n%s" % (product.display_name,
                    product.description_sale) or product.display_name or product.name,
            }
            line_obj.create(cr, uid, values, context=context)

        return from_cart_id

    def _merge_temp_cart(self, cr, uid, cart_id, partner_id, context=None):
        if not partner_id:
            return cart_id

        cart_ids = self.search(cr, SUPERUSER_ID, [('partner_id', '=', partner_id), ('state', '=', 'draft'), ('temp', '=', False)], order='id desc', limit=1, context=context)

        if not cart_ids:
            return cart_id

        return self._merge_cart_from_temp(cr, uid, cart_ids[0], cart_id, context=context)

    def _cart_accessories(self, cr, uid, ids, context=None):
        for cart in self.browse(cr, uid, ids, context=context):
            s = set(j.id for l in (cart.cart_line or []) for j in (l.product_id.accessory_product_ids or []))
            s -= set(l.product_id.id for l in cart.cart_line)

            # sample函数，在s中获取随机的样本值
            product_ids = random.sample(s, min(len(s), 3))
            return self.pool['product.product'].browse(cr, uid, product_ids, context=context)

    def search_line_by_product(self, cr, uid, ids, product_id, context=None):
        for cart in self.browse(cr, uid, ids, context=context):
            for line in cart.cart_line:
                if line.state == 'draft' and line.product_id.id == product_id:
                    return line.id

            return None

    def _cart_update(self, cr, uid, ids, product_id=None, line_id=None, add_qty=0, set_qty=0, context=None, **kwargs):
        line_obj = self.pool.get('shopping.cart.line')

        quantity = 0
        product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)

        for cart in self.browse(cr, uid, ids, context=context):
            line_id = cart.search_line_by_product(product_id, context=context)
            if not line_id:
                values = {
                    'order_id': cart.id,
                    'product_id': product_id,
                    'product_uom_qty': set_qty or add_qty,
                    'name': product.description_sale and "%s\n%s" % (product.display_name,
                        product.description_sale) or product.display_name or product.name,
                    'taxes_id': [[4, tax.id] for tax in product.taxes_id],
                }

                line_id = line_obj.create(cr, SUPERUSER_ID, values, context=context)
                return {'line_id': line_id, 'quantity': set_qty or add_qty}

            if set_qty:
                quantity = set_qty
            elif add_qty:
                quantity = line_obj.browse(cr, SUPERUSER_ID, line_id, context=context).product_uom_qty + (add_qty or 0)

            if quantity <= 0:
                line_obj.unlink(cr, SUPERUSER_ID, [line_id], context=context)
            else:
                line_obj.write(cr, SUPERUSER_ID, [line_id], {'product_uom_qty': quantity}, context=context)

        return {'line_id': line_id, 'quantity': quantity}

    def get_cart_line_info(self, cr, uid, ids, context=None):
        res = []
        line_obj = self.pool.get('shopping.cart.line')
        for cart in self.browse(cr, uid, ids, context=context):
            for line in cart.cart_line:
                if line.state == 'draft':
                    res.append(line_obj._get_cart_line_info(line))

        return res


class shopping_cart_line(osv.osv):
    _name = 'shopping.cart.line'

    def _get_cart_line_info(self, line):
        return {
            'id': line.id,
            'product_name': line.product_id.name,
            'product_id': line.product_id.id,
            'template_id': line.product_id.product_tmpl_id.id,
            'product_group': (line.product_id.start_sale_time or line.product_id.end_sale_time) and True or False,
            'reserve_quantity': line.product_id.reserve_quantity,
            'minimum_quantity': line.product_id.minimum_quantity,
            'price_unit': line.price_unit,
            'product_uom_qty': line.product_uom_qty,
            'name': line.name,
            'price_subtotal': line.price_subtotal,
            'state': line.state,
            'create_date': line.create_date,
            'choose': False,
            'delete': False,
            'variant': ' '.join(['%s:%s' % (attr.attribute_id.name, attr.name) \
                                 for attr in line.product_id.attribute_value_ids]),
        }

    def get_cart_line_info(self, cr, uid, ids, context=None):
        res = []
        for line in self.browse(cr, uid, ids, context=context):
            res.append(self._get_cart_line_info(line))

        return res

    def _get_price_unit(self, cr, uid, ids, field_name, arg, context=None):
        res = {}
        # TODO 需要一个详细的获取订单行的单价的算法
        # 使用购物车上的价格表来换算单价，价格表取自客户上的价格表
        for line in self.browse(cr, uid, ids, context=context):
            pricelist_id = line.order_id.pricelist_id.id or line.order_id.partner_id.property_product_pricelist.id
            price = 0
            if pricelist_id:
                prices = self.pool.get('product.pricelist').price_rule_get_multi(cr, uid, [pricelist_id], [(line.product_id, line.product_uom_qty, line.order_id.partner_id)])
                price = prices[line.product_id.id][pricelist_id][0]

            price = price or line.product_id.lst_price
            if line.order_id.shop_id.type == 'integral':
                price = math.ceil(price)
            res.update({line.id: price})
        return res

    def _get_line_from_cart(self, cr, uid, ids, context=None):
        return [line.id for cart in self.browse(cr, uid, ids, context=context) for line in cart.cart_line]

    def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
        tax_obj = self.pool.get('account.tax')
        cur_obj = self.pool.get('res.currency')

        res = {}
        for line in self.browse(cr, uid, ids, context=context):
            taxes = tax_obj.compute_all(cr, uid, line.taxes_id, line.price_unit, line.product_uom_qty, line.product_id, line.order_id.partner_id)
            cur = line.order_id.pricelist_id.currency_id
            res[line.id] = cur_obj.round(cr, uid, cur, taxes['total'])

        return res

    _columns = {
        'order_id': fields.many2one('shopping.cart', u'购物车订单'),
        'taxes_id': fields.many2many('account.tax', string=u'销项税'),
        'product_id': fields.many2one('product.product', u'产品'),
        'price_unit': fields.function(_get_price_unit, type='float', string=u'单价'),
        # 'shopping.cart.line': (lambda self, cr, uid, ids, ctx=None: ids, ['product_id', 'order_id'], 10),
        # 'shopping.cart': (_get_line_from_cart, ['pricelist_id', 'partner_id'], 10),
        # }),
        'product_uom_qty': fields.float(u'数量'),
        'name': fields.char(u'描述'),
        'company_id': fields.related('order_id', 'company_id', type='many2one', relation='res.company', string=u'公司'),
        'price_subtotal': fields.function(_amount_line, string=u'总额'),
        'state': fields.selection([('draft', u'使用中'), ('done', u'完成'), ('delete', u'已删除')], string=u'状态'),
        'create_date': fields.datetime(u'创建日期'),
    }

    _defaults = {
        'state': 'draft',
    }


class website(orm.Model):
    _inherit = 'website'

    def _sale_get_order(self, cr, uid, ids, force_create=False, prepare_vals=None, code=None,
            update_pricelist=None, context=None):

        sale_order_obj = self.pool['sale.order']
        cart_obj = self.pool.get('shopping.cart')
        sale_order_id = request.session.get('sale_order_id')
        sale_order = None
        # create so if needed
        if not sale_order_id and (force_create or code):
            # TODO cache partner_id session
            # 需要订单管理功能
            partner = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id
            cart_id = request.session.get('cart_id')
            if cart_id:
                sale_order_id = cart_obj.create_sale_order(cr, uid, cart_id, context=context)

            if not sale_order_id:
                for w in self.browse(cr, uid, ids):
                    values = {
                        'shop_id': request.session.get('shop_id'),
                        'user_id': w.user_id.id,
                        'partner_id': partner.id,
                        'pricelist_id': partner.property_product_pricelist.id,
                        'section_id': self.pool.get('ir.model.data').get_object_reference(cr, uid, 'website', 'salesteam_website_sales')[1],
                        'order_line': prepare_vals and [[0, False, val] for val in prepare_vals] or False,
                    }

                    sale_order_id = sale_order_obj.create(cr, SUPERUSER_ID, values, context=context)

            values = sale_order_obj.onchange_partner_id(cr, SUPERUSER_ID, [], partner.id, context=context)['value']
            sale_order_obj.write(cr, SUPERUSER_ID, [sale_order_id], values, context=context)
            request.session['sale_order_id'] = sale_order_id

        if sale_order_id:
            # TODO cache partner_id session
            partner = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id

            sale_order = sale_order_obj.browse(cr, SUPERUSER_ID, sale_order_id, context=context)
            if not sale_order.exists():
                request.session['sale_order_id'] = None
                return None

            # check for change of pricelist with a coupon
            if code and code != sale_order.pricelist_id.code:
                pricelist_ids = self.pool['product.pricelist'].search(cr, SUPERUSER_ID, [('code', '=', code)], context=context)
                if pricelist_ids:
                    pricelist_id = pricelist_ids[0]
                    request.session['sale_order_code_pricelist_id'] = pricelist_id
                    update_pricelist = True

            pricelist_id = request.session.get('sale_order_code_pricelist_id') or partner.property_product_pricelist.id

            # check for change of partner_id ie after signup
            if sale_order.partner_id.id != partner.id and request.website.partner_id.id != partner.id:
                flag_pricelist = False
                if pricelist_id != sale_order.pricelist_id.id:
                    flag_pricelist = True
                fiscal_position = sale_order.fiscal_position and sale_order.fiscal_position.id or False

                values = sale_order_obj.onchange_partner_id(cr, SUPERUSER_ID, [sale_order_id], partner.id, context=context)['value']
                if values.get('fiscal_position'):
                    order_lines = map(int, sale_order.order_line)
                    values.update(sale_order_obj.onchange_fiscal_position(cr, SUPERUSER_ID, [],
                        values['fiscal_position'], [[6, 0, order_lines]], context=context)['value'])

                values['partner_id'] = partner.id
                sale_order_obj.write(cr, SUPERUSER_ID, [sale_order_id], values, context=context)

                if flag_pricelist or values.get('fiscal_position', False) != fiscal_position:
                    update_pricelist = True

            # update the pricelist
            if update_pricelist:
                values = {'pricelist_id': pricelist_id}
                values.update(sale_order.onchange_pricelist_id(pricelist_id, None)['value'])
                sale_order.write(values)
                for line in sale_order.order_line:
                    if line.exists():
                        sale_order._cart_update(product_id=line.product_id.id, line_id=line.id, add_qty=0)

            # update browse record
            if (code and code != sale_order.pricelist_id.code) or sale_order.partner_id.id != partner.id:
                sale_order = sale_order_obj.browse(cr, SUPERUSER_ID, sale_order.id, context=context)

        return sale_order

    def sale_get_order(self, cr, uid, ids, force_create=False, prepare_vals=None, code=None,
            update_pricelist=None, context=None):

        if hasattr(request, 'rerouting') and request.rerouting and isinstance(request.rerouting, list) and request.rerouting[-1] == '/page/homepage':
            request.session['get_cart'] = True

        if request.session.get('get_cart'):
            return self.sale_get_cart(cr, uid, ids, force_create=force_create, code=code,
                update_pricelist=update_pricelist, context=context)
        else:
            return self._sale_get_order(cr, uid, ids, force_create=force_create, prepare_vals=prepare_vals, code=code,
                update_pricelist=update_pricelist, context=context)

    def sale_get_cart(self, cr, uid, ids, force_create=False, code=None,
            update_pricelist=None, context=None):

        cart_obj = self.pool.get('shopping.cart')
        cart_id = request.session.get('cart_id')
        if cart_id:
            cart = cart_obj.browse(cr, SUPERUSER_ID, cart_id, context=context)
            if not cart.exists() or cart.state == 'done' or cart.shop_id.id != request.session.get('shop_id'):
                cart_id = None
                request.session['cart_id'] = None

        if not cart_id:
            partner = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id
            cart_ids = []
            if request.session.get('login'):
                cart_ids = cart_obj.search(cr, SUPERUSER_ID, [('partner_id', '=', partner.id),
                                                              ('state', '=', 'draft'),
                                                              ('temp', '=', False),
                                                              ('shop_id', '=', request.session.get('shop_id'))],
                                           order='id desc', limit=1, context=context)

            if cart_ids:
                cart_id = cart_ids[0]
            else:
                for w in self.browse(cr, uid, ids):
                    values = {
                        'user_id': w.user_id.id,
                        'partner_id': partner.id,
                        'pricelist_id': partner.property_product_pricelist.id,
                        'shop_id': request.session.get('shop_id'),
                        'temp': not request.session.get('login', False) and True or False,
                    }

                    cart_id = cart_obj.create(cr, SUPERUSER_ID, values, context=context)

            request.session['cart_id'] = cart_id

        if cart_id:
            partner = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id

            cart = cart_obj.browse(cr, SUPERUSER_ID, cart_id, context=context)
            if not cart.exists():
                request.session['cart_id'] = None
                return None

            if cart.temp and request.session.get('login'):
                cart_id = cart_obj._merge_temp_cart(cr, uid, cart_id, partner.id, context=context)
                request.session['cart_id'] = cart_id
                cart_obj.write(cr, SUPERUSER_ID, cart_id, {'temp': False}, context=context)

                cart = cart_obj.browse(cr, SUPERUSER_ID, cart_id, context=context)

            pricelist_id = False
            if code and code != cart.pricelist_id.code:
                pricelist_ids = self.pool['product.pricelist'].search(cr, SUPERUSER_ID, [('code', '=', code)], context=context)
                if pricelist_ids:
                    pricelist_id = pricelist_id

            pricelist_id = pricelist_id or partner.property_product_pricelist.id

            if cart.partner_id.id != partner.id and request.website.partner_id.id != partner.id:
                cart_obj.write(cr, SUPERUSER_ID, [cart_id], {
                        'partner_id': partner.id,
                        'pricelist_id': pricelist_id,
                    }, context=context)

            if (code and code != cart.pricelist_id.code) or cart.partner_id.id != partner.id:
                cart.refresh()

        return cart
